package com.av.client.frames;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDesktopPane;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.text.DateFormatter;

import org.jdesktop.swingx.JXDatePicker;
import org.jdesktop.swingx.JXErrorPane;
import org.jdesktop.swingx.error.ErrorInfo;

import com.av.client.components.AvButton;
import com.av.client.components.AvComponent;
import com.av.client.components.AvLabel;
import com.av.client.util.idioma.Error;
import com.av.client.util.idioma.Etiqueta;
import com.av.client.util.idioma.ManejadorIdiomas;
import com.av.client.util.idioma.ManejadorIdiomas.IdiomaEvent;
import com.av.client.util.idioma.ManejadorIdiomas.IdiomaEventListener;
import com.av.client.util.sesion.AdministradorSesion;
import com.av.db.dataobjects.EntradaSalida;
import com.av.db.dataobjects.Tarjeta;
import com.av.db.dataobjects.enums.Rol;
import com.av.exceptions.AvException;
import com.av.rmi.CatalogoAcciones;
import com.av.rmi.Parametro;
import com.av.rmi.Parametro.Tipo;

@SuppressWarnings("serial")
public class EntradaSalidaFrame extends JInternalFrame {

	private static final int WIDTH = 375;
	private static final int HEIGHT = 200;

	private AvLabel lblTarjeta;
	private JComboBox cboTarjeta;
	private AvLabel lblFecha;
	private JXDatePicker dtFecha;
	private AvLabel lblHora;
	private JFormattedTextField txtHora;
	private JCheckBox chkEntrada;
	private AvButton btnAgregar;
	private AvButton btnCerrar;

	private ManejadorIdiomas mi;
	private BotonHandler bh = new BotonHandler();
	private EntradaSalida entradaSalida;

	public EntradaSalidaFrame() {
		super();
		mi = ManejadorIdiomas.getInstance();
		initComponents();
		addListeners();
		cargarPermisos();
		limpiarTextos();
	}// TarjetaFrame

	/**
	 * Funcion que habilita o deshabilita los componentes de acuerdo a sus
	 * permisos asignados
	 */
	private void cargarPermisos() {
		if (AdministradorSesion.getInstance().getSesionActiva() != null) {
			Rol r = AdministradorSesion.getInstance().getSesionActiva()
					.getUsuario().getRol();
			for (Component c : this.getContentPane().getComponents()) {
				if (c instanceof JPanel) {
					for (Component c2 : ((JPanel) c).getComponents()) {
						if (c2 instanceof AvComponent) {
							c2.setEnabled(((AvComponent) c2).contains(r));
						}
					}
				} else if (c instanceof AvComponent) {
					c.setEnabled(((AvComponent) c).contains(r));
				}
			}
		}
	}// cargarPermisos

	private void limpiarTextos() {
		cboTarjeta.setSelectedIndex(-1);
		dtFecha.setDate(new Date());
		txtHora.setValue(new Date());
	}// limpiarTextos

	private void addListeners() {
		mi.addIdiomaEventListener(new IdiomaEventListener() {
			@Override
			public void changedIdiomaEvent(IdiomaEvent evt) {
				setLabels();
			}
		});

		btnAgregar.addActionListener(bh);
		btnCerrar.addActionListener(bh);
	}// addListeners

	private void setLabels() {
		setTitle(mi.obtenerEtiqueta(Etiqueta.ENTRADA_SALIDA_FRAME_TITLE));
		lblTarjeta.setText(Etiqueta.ENTRADA_SALIDA_FRAME_LBL_TARJETA);
		lblFecha.setText(Etiqueta.ENTRADA_SALIDA_FRAME_LBL_FECHA);
		dtFecha.setLocale(mi.getIdioma().getLocale());
		lblHora.setText(Etiqueta.ENTRADA_SALIDA_FRAME_LBL_HORA);
		btnAgregar.setText(Etiqueta.TARJETA_FRAME_BTN_AGREGAR);
		btnCerrar.setText(Etiqueta.TARJETA_FRAME_BTN_CERRAR);
	}// setLabels

	private void initComponents() {
		setTitle(mi.obtenerEtiqueta(Etiqueta.ENTRADA_SALIDA_FRAME_TITLE));
		setLayout(new GridBagLayout());
		GridBagConstraints gc = new GridBagConstraints();

		gc.insets = new Insets(5, 5, 5, 5);
		gc.fill = GridBagConstraints.HORIZONTAL;

		// Tarjeta
		gc.gridx = 0;
		lblTarjeta = new AvLabel(Etiqueta.ENTRADA_SALIDA_FRAME_LBL_TARJETA);
		add(lblTarjeta, gc);

		gc.gridx = 1;
		gc.weightx = 1.0;
		gc.gridwidth = 3;
		cboTarjeta = new JComboBox(obtenerTarjetasActivas());
		add(cboTarjeta, gc);
		gc.weightx = 0.0;
		gc.gridwidth = 1;

		// Fecha
		gc.gridy = 1;
		gc.gridx = 0;
		lblFecha = new AvLabel(Etiqueta.ENTRADA_SALIDA_FRAME_LBL_FECHA);
		add(lblFecha, gc);

		gc.gridx = 1;
		gc.weightx = 1.0;
		dtFecha = new JXDatePicker();
		dtFecha.setLocale(mi.getIdioma().getLocale());
		add(dtFecha, gc);
		gc.weightx = 0.0;

		// Hora
		gc.gridx = 2;
		lblHora = new AvLabel(Etiqueta.ENTRADA_SALIDA_FRAME_LBL_HORA);
		add(lblHora, gc);

		gc.gridx = 3;
		gc.weightx = 1.0;
		txtHora = new JFormattedTextField(new DateFormatter(
				new SimpleDateFormat("HH:mm")));
		add(txtHora, gc);
		gc.weightx = 0.0;

		// Entrada
		gc.gridy = 2;
		gc.gridx = 0;
		gc.gridwidth = 4;
		chkEntrada = new JCheckBox(mi
				.obtenerEtiqueta(Etiqueta.ENTRADA_SALIDA_FRAME_CHK_ENTRADA));
		add(chkEntrada, gc);
		gc.gridwidth = 1;

		// Agregar
		JPanel jpnl = new JPanel(new FlowLayout());

		btnAgregar = new AvButton(Etiqueta.TARJETA_FRAME_BTN_AGREGAR);
		btnAgregar.addPermiso(Rol.ADMIN);
		jpnl.add(btnAgregar);

		btnCerrar = new AvButton(Etiqueta.TARJETA_FRAME_BTN_CERRAR);
		btnCerrar.loadPermisos();
		jpnl.add(btnCerrar);

		gc.gridy = 4;
		gc.gridx = 0;
		gc.gridwidth = 4;
		gc.weightx = 1.0;
		add(jpnl, gc);
		gc.gridwidth = 1;
		gc.weightx = 0.0;

		setClosable(false);
		setSize(WIDTH, HEIGHT);
	}// initComponents

	/**
	 * Funcion que obtiene todas las tarjetas activas del sistema
	 * 
	 * @return
	 */
	private Tarjeta[] obtenerTarjetasActivas() {
		Tarjeta[] tmp = new Tarjeta[1];
		Parametro p = new Parametro();

		if (AdministradorSesion.getInstance().getSesionActiva() != null) {
			try {
				p.setAccion(CatalogoAcciones.OBTENER_ACTIVOS_TARJETA);
				p = AdministradorSesion.getInstance().getSesionActiva()
						.ejecutar(p);
				if (p.getValor(Tipo.OUTPUT) != null) {
					tmp = (Tarjeta[]) p.getValor(Tipo.OUTPUT);
				}
			} catch (AvException e) {
				ErrorInfo info = new ErrorInfo(getTitle() + " - ERROR", e
						.getMessage(), null, null, e, Level.INFO, null);
				JXErrorPane.setDefaultLocale(mi.getIdioma().getLocale());
				JXErrorPane.showDialog(getParent(), info);

			}
		}

		return tmp;
	}// obtenerTarjetasActivas

	private class BotonHandler implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent ev) {
			Object o = ev.getSource();
			if (o instanceof AvButton) {
				if (o == btnCerrar) {
					dispose();
				} else if (o == btnAgregar) {
					try {
						validarTextos();
						agregarEntradaSalida();
					} catch (AvException e) {
						ErrorInfo info = new ErrorInfo(getTitle() + " - ERROR",
								e.getMessage(), null, null, e, Level.WARNING,
								null);
						JXErrorPane
								.setDefaultLocale(mi.getIdioma().getLocale());
						JXErrorPane.showDialog(getParent(), info);
					}
				}
			}
		}// actionPerformed
	}// BotonHandler

	private void agregarEntradaSalida() throws AvException {
		Parametro p = new Parametro();
		p.setAccion(CatalogoAcciones.AGREGAR_ENTRADA_SALIDA);
		p.setValor(Tipo.INPUT, getEntradaSalida());
		AdministradorSesion.getInstance().getSesionActiva().ejecutar(p);
		limpiarTextos();
	}// agregarEntradaSalida

	/**
	 * Funcion que obtiene la entrada o salida a partir de los datos
	 * introducidos por el usuario
	 * 
	 * @return
	 */
	private EntradaSalida getEntradaSalida() {
		if (entradaSalida == null) {
			entradaSalida = new EntradaSalida();
		}

		entradaSalida.setEntrada(chkEntrada.isSelected());
		entradaSalida.setFecha(obtenerFecha());
		entradaSalida.setTarjeta((Tarjeta) cboTarjeta.getSelectedItem());

		return entradaSalida;
	}// getEntradaSalida

	/**
	 * Obtiene la fecha y hora que el usuario a ingresado
	 * 
	 * @return
	 */
	private Date obtenerFecha() {
		Calendar c = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c.setTime(dtFecha.getDate());
		c2.setTime((Date) txtHora.getValue());
		c.set(Calendar.HOUR_OF_DAY, c2.get(Calendar.HOUR_OF_DAY));
		c.set(Calendar.MINUTE, c2.get(Calendar.MINUTE));

		return c.getTime();
	}// obtenerFecha

	/**
	 * Valida los campos ingresados por el usuario
	 * 
	 * @throws AvException
	 */
	private void validarTextos() throws AvException {
		if (cboTarjeta.getSelectedIndex() < 0) {
			cboTarjeta.requestFocus();
			throw new AvException(mi
					.obtenerError(Error.ENTRADA_SALIDA_FRAME_CBO_TARJETA));
		}

		if (txtHora.getText() == null || txtHora.getText().trim().length() == 0) {
			txtHora.requestFocus();
			throw new AvException(mi
					.obtenerError(Error.ENTRADA_SALIDA_FRAME_TXT_HORA));
		}

		Date hoy = new Date();
		if (hoy.before(obtenerFecha())) {
			dtFecha.requestFocus();
			throw new AvException(mi
					.obtenerError(Error.ENTRADA_SALIDA_FRAME_DT_FECHA));
		}
	}// validarTextos

	public static void main(String[] args) {
		JFrame tmp = new JFrame("Test");
		tmp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JDesktopPane desktop = new JDesktopPane();
		desktop.setBackground(Color.GRAY);
		desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
		tmp.setContentPane(desktop);

		EntradaSalidaFrame ea = new EntradaSalidaFrame();
		ea.setVisible(true);
		desktop.add(ea);
		try {
			ea.setSelected(true);
		} catch (PropertyVetoException e) {
		}
		tmp.setSize(new Dimension(ea.getWidth() + 100, ea.getHeight() + 100));
		tmp.setVisible(true);
	}// main
}// EntradaSalidaFrame
